#ifndef __PARSEMESSAGE_H__
#define __PARSEMESSAGE_H__

#include "common.h"
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/sendfile.h>
#include <queue>
#include <sys/socket.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <ctime>
#include "openssl.h" 

class HttpResponse
{
  public:
    HttpResponse();

    void clear();

    std::string& getRespLine();
    const std::vector<std::string>& getRespHeader();
    void addRespHeader(std::string& str);
    const std::string& getRespBlank ();
  private:
    std::string resp_line_;
    std::vector<std::string> resp_header_;
    std::string blank_;
    std::string resp_body_;
};

class HttpRequest
{
  public:
    HttpRequest();
    ~HttpRequest();

    void clear();

    bool isLegalMethod();
    bool isGetMethod();
    bool isPostMethod();

    std::string getPath();
    void setPath(const std::string& path);
    bool getCgi();
    void setCgi();
    void setFileSize(size_t size);
    void setFileMtime(std::time_t mtime);
    std::string getPathSuffix();
    size_t getFileSize();
    std::time_t getFileMtime();
    const std::string& getMethod();
    const std::string& getParam();
    const std::string& getBody();

    bool parseUrl();
    bool setUrlToPath();
    void addHomePage();
    bool parseReqMsg(const char* msg, int msglen);
  private:
    std::string req_line_;//请求行
    std::vector<std::string> req_header_;//请求报头
    std::string req_blank_;//空行
    std::string req_body_;//请求正文

  private:
    std::string method_;
    std::string url_;
    std::string version_;
    
    std::string path_;//请求资源路径
    std::string param_;//参数
    bool iscgi_;//是否使用cgi技术
    size_t filesize_;
    std::time_t file_mtime_;//文件修改时间
  private:
    std::map<std::string, std::string> header_map_;
    uint32 content_length_;//正文长度

};

class HttpEndPoint
{
  public:
    HttpEndPoint(int sock = 0, SSL* ssl = nullptr);
    ~HttpEndPoint();
    bool parseHttpMsg(const char* msg, int msglen);
    
    void clear();
    void setHttpEndPoint(int sock);

    bool handleRequest(const char* msg, int msglen);
    bool makeRespLine(size_t code);
    bool makeRespHeader();
    bool makeResponse();//加入到epoll中

    bool sendResponse();
    bool sendOpensslResp();

    bool exeNoCgi();
    bool exeCgi();
    bool exeNoCgiOpenssl();
    bool exeCgiOpenssl();
  private:
    HttpResponse resp_;
    HttpRequest req_;
    int sock_;
    SSL* ssl_;
};

#endif
